/*
    This file is part of Posixcpp library.

    Posixcpp library is free software: you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public License
    as published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Posixcpp library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU LesserGeneral Public
    License along with Posixcpp library. If not, see
    <http://www.gnu.org/licenses/>.
*/

#ifndef POSIXCPP_HPP_INCLUDED
#define POSIXCPP_HPP_INCLUDED

#include <system_error>
#include <stdexcept>
#include <string>
#include <ostream>

/**
 * @namespace posix
 * @brief POSIX C++ wrapper namespace
 */
namespace posix
{

}

#define LINE_NUM(x) __STRING(x)

#ifdef POSIXCPP_USE_CONTRACTS

#define POSIX_CALL_ASSERT(condition) \
if ( !(condition) ) \
{ \
	throw std::system_error(errno, std::system_category()); \
}

#define POSIX_CALL_ASSERT_X(condition, message) \
if ( !(condition) ) \
{ \
	throw std::system_error(errno, std::system_category(), \
        std::string("Call condition ").append( #condition ).append(" at "). \
        append(__FILE__).append(":").append(LINE_NUM( __LINE__ )).append(" "). \
        append(message)); \
}

#define PRECONDITION_ASSERT( condition, message ) \
if ( !(condition) ) \
{ \
	throw std::logic_error( std::string("\n[PRECONDITION VIOLATION] ").append( \
		__PRETTY_FUNCTION__).append(": ").append(message).append("\n\tCondition \"" #condition \
		"\" not met in file " __FILE__ " line " LINE_NUM( __LINE__ )) ); \
}
#define POSTCONDITION_ASSERT( condition, message ) \
if ( !(condition) ) \
{ \
	throw std::logic_error( std::string("\n[POSTCONDITION VIOLATION] ").append( \
		__PRETTY_FUNCTION__).append(": ").append(message).append("\n\tCondition \"" #condition \
		"\" not met in file " __FILE__ " line " LINE_NUM( __LINE__ )) ); \
}
#define INVARIANT_ASSERT( condition, message ) \
if ( !(condition) ) \
{ \
	throw std::logic_error( std::string("\n[INVARIANT VIOLATION] ").append( \
		__PRETTY_FUNCTION__).append(": ").append(message).append("\n\tCondition \"" #condition \
		"\" not met in file " __FILE__ " line " LINE_NUM( __LINE__ )) ); \
}
#else
#define POSIX_CALL_ASSERT(condition) \
if ( !(condition) ) \
{ \
	throw std::system_error(errno, std::system_category()); \
}	
#define POSIX_CALL_ASSERT_X(condition, message) \
if ( !(condition) ) \
{ \
	throw std::system_error(errno, std::system_category(), message); \
}	
#define PRECONDITION_ASSERT( condition, message )
#define POSTCONDITION_ASSERT( condition, message )
#define INVARIANT_ASSERT( condition, message )
#endif


#endif // POSIXCPP_HPP_INCLUDED
